/*
 * Copyright 2014 Davy Maddelein.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.compomics.pepshell.view.dataviewing;

import com.compomics.pepshell.FaultBarrier;
import com.compomics.pepshell.model.AnalysisGroup;
import com.compomics.pepshell.model.Experiment;
import com.compomics.pepshell.model.protein.proteinimplementations.PepshellProtein;
import com.compomics.pepshell.view.drawmodes.DrawModeUtilities;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.sql.SQLException;
import java.util.List;
import javax.swing.BorderFactory;

/**
 *
 * @author Davy Maddelein
 */
public class ProteinDetailPanel extends javax.swing.JPanel {

    private Experiment referenceExperiment;
    private PepshellProtein referenceProtein;

    public ProteinDetailPanel() {
        initComponents();
        experimentsScrollPane.getViewport().setOpaque(false);
        experimentsScrollPane.setViewportBorder(BorderFactory.createEmptyBorder());
        experimentsScrollPane.getHorizontalScrollBar().setModel(referenceExperimentPanel.getHorizontalScrollBarModel());
    }

    public ProteinDetailPanel(Experiment referenceExperiment, AnalysisGroup aGroup) {
        this();
        this.referenceExperiment = referenceExperiment;
        setExperimentsToDisplay(aGroup.getExperiments());
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        referenceExperimentPanel = new com.compomics.pepshell.view.dataviewing.ReferenceExperimentPanel();
        experimentsScrollPane = new javax.swing.JScrollPane();
        experimentAggregatorPanel = new ExperimentAggregatorPanel();
        sequenceCoveragePanel = new com.compomics.pepshell.view.dataviewing.SequenceCoveragePanel();

        setBackground(new java.awt.Color(255, 255, 255));
        setBorder(javax.swing.BorderFactory.createTitledBorder("protein details"));

        referenceExperimentPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("reference protein"));
        referenceExperimentPanel.setPreferredSize(new java.awt.Dimension(1000, 227));

        experimentsScrollPane.setBackground(new java.awt.Color(255, 255, 255));
        experimentsScrollPane.setBorder(javax.swing.BorderFactory.createTitledBorder("experiments"));

        experimentAggregatorPanel.setPreferredSize(new java.awt.Dimension(200, 100));
        experimentAggregatorPanel.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseExited(java.awt.event.MouseEvent evt) {
                experimentsPanelMouseExited(evt);
            }
        });

        javax.swing.GroupLayout experimentsPanelLayout = new javax.swing.GroupLayout(experimentAggregatorPanel);
        experimentAggregatorPanel.setLayout(experimentsPanelLayout);
        experimentsPanelLayout.setHorizontalGroup(
            experimentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 540, Short.MAX_VALUE)
        );
        experimentsPanelLayout.setVerticalGroup(
            experimentsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 148, Short.MAX_VALUE)
        );

        experimentsScrollPane.setViewportView(experimentAggregatorPanel);

        sequenceCoveragePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("sequence coverage"));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(sequenceCoveragePanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 552, Short.MAX_VALUE)
                    .addComponent(referenceExperimentPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
                    .addComponent(experimentsScrollPane))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(referenceExperimentPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 265, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(experimentsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 171, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(sequenceCoveragePanel, javax.swing.GroupLayout.PREFERRED_SIZE, 170, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

    private void experimentsPanelMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_experimentsPanelMouseExited
        // TODO add your handling code here:
        sequenceCoveragePanel.repaint();

    }//GEN-LAST:event_experimentsPanelMouseExited

    public void updateProteinGraphics(PepshellProtein pepshellProteinOfInterest) throws SQLException {
        try{
            sequenceCoveragePanel.showProteinCoverage(pepshellProteinOfInterest.getProteinSequence(), pepshellProteinOfInterest, true);
        } catch (ArrayIndexOutOfBoundsException aix){
            FaultBarrier.getInstance().handleException(aix);
        }
        referenceProtein = pepshellProteinOfInterest;
        this.revalidate();
        this.repaint();
        referenceExperimentPanel.updateProtein(pepshellProteinOfInterest);
        referenceExperimentPanel.revalidate();
        referenceExperimentPanel.repaint();
        experimentAggregatorPanel.setReferenceProtein(referenceProtein);
        this.updatePeptideGraphics(pepshellProteinOfInterest);
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private ExperimentAggregatorPanel experimentAggregatorPanel;
    private javax.swing.JScrollPane experimentsScrollPane;
    private com.compomics.pepshell.view.dataviewing.ReferenceExperimentPanel referenceExperimentPanel;
    private com.compomics.pepshell.view.dataviewing.SequenceCoveragePanel sequenceCoveragePanel;
    // End of variables declaration//GEN-END:variables

    /**
     * sets the project do display the peptides from in relation to the
     * reference experiment
     *
     * @param experiments the experiments to show and compare
     * @param condense should the experiments be treated as a group or not
     */
    public void setExperimentsToDisplay(List<Experiment> experiments, boolean condense) {
        experimentAggregatorPanel.setLayout(new GridBagLayout());
        for (int i = 0; i < experiments.size(); i++) {
            GridBagConstraints gridBagConstraints = new GridBagConstraints();
            gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
            gridBagConstraints.weightx = 1.0;
            gridBagConstraints.weighty = 1.0;
            gridBagConstraints.gridy = i;
            gridBagConstraints.anchor = GridBagConstraints.FIRST_LINE_START;
            ExperimentPanel panel = new ExperimentPanel(experiments.get(i));
            panel.setExperiment(experiments.get(i));
            panel.setYOffset(panel.getSize().getHeight() * i);
            //change with smarter clustering jpanel
            experimentAggregatorPanel.add(panel, gridBagConstraints);
        }
        experimentAggregatorPanel.revalidate();
        experimentAggregatorPanel.repaint();
    }

    public Experiment getReferenceExperiment() {
        return referenceExperiment;
    }

    public void setReferenceExperiment(Experiment aReferenceExperiment) {
        this.referenceExperiment = aReferenceExperiment;
        referenceExperimentPanel.setReferenceExperiment(referenceExperiment);
    }

    final void setExperimentsToDisplay(List<Experiment> experiments) {
        setExperimentsToDisplay(experiments, true);
    }


    private void updatePeptideGraphics(PepshellProtein aProtein) {
        for (int i = 0; i < experimentAggregatorPanel.getComponents().length; i++) {
            ((ExperimentPanel) experimentAggregatorPanel.getComponent(i)).setPepshellProtein(aProtein);
        }
    }

    void setSequenceCoverage(String proteinSequence, PepshellProtein pepshellProtein) {
        // this is a very quick fix to get updating sequence coverage but has to be refined
        sequenceCoveragePanel.showProteinCoverage(proteinSequence, pepshellProtein, false);
    }

    protected void setSequenceCoverageToOriginal() {
        if (!sequenceCoveragePanel.isOriginalCoverage()) {
            sequenceCoveragePanel.setOriginalCoverage();
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (referenceProtein != null) {
            try {
            double tempscale = (double) (referenceExperimentPanel.getWidth() - 100) / referenceProtein.getProteinSequence().length();
            if (tempscale < 1) {
                DrawModeUtilities.setScale(1.0);
            } else {
                DrawModeUtilities.setScale(tempscale);
            }
            } catch (NumberFormatException ex) {
                FaultBarrier.getInstance().handleException(ex);
            }
        }
    }
}
